# 导入 OpenCV 库，用于图像处理和计算机视觉任务，如绘制检测框、保存图像等
import cv2
# 导入 PyAutoGUI 库，用于自动化鼠标和键盘操作，如点击、移动鼠标、按下热键等
import pyautogui
# 从 ultralytics 库中导入 YOLO 类，用于加载和运行 YOLOv8 目标检测模型
from ultralytics import YOLO
# 导入 time 库，用于处理时间相关的操作，如添加延迟
import time
# 导入 sys 库，用于与 Python 解释器进行交互，这里主要用于获取 Python 解释器的路径
import sys
# 导入 os 库，用于与操作系统进行交互，如文件和目录操作
import os
# 导入 subprocess 库，用于创建新的进程，这里用于启动另一个 Python 脚本
import subprocess
# 从自定义模块 moveFb模块 中导入 movefb 函数，用于执行特定的鼠标移动和点击操作
from moveFb模块 import movefb
# 导入 win32gui 库，用于 Windows 系统的窗口操作，如查找窗口、获取窗口坐标等
import win32gui
# 导入自定义模块 检测框模块，用于获取游戏窗口的截图
import 检测框模块
# 从自定义模块 find_class_module 中导入 find_class_and_perform_action 函数，用于查找特定类别的目标并执行相应动作
from find_class_module import find_class_and_perform_action
# 从自定义模块 yolo2.find_and_perform_action_module 中导入 find_and_perform_action 函数，用于查找目标并执行动作
from yolo2.find_and_perform_action_module import find_and_perform_action
# 从自定义模块 yolo2.yolo找图模块 中导入 click_target_image 函数，用于点击目标图像
from yolo2.yolo找图模块 import click_target_image
# 从自定义模块 yolo2.循环找图模块 中导入 run_action_condition_found 和 run_action_condition_not_found 函数，用于根据条件执行动作
from yolo2.循环找图模块 import run_action_condition_found, run_action_condition_not_found
from yolo2.循环找图模块2 import run_action_until_image_disappears

# 检查检测框模块是否正确加载
if hasattr(检测框模块, 'MODULE_LOADED') and 检测框模块.MODULE_LOADED:
    print("检测框模块已正确加载")
else:
    print("检测框模块加载失败")

# 定义一个函数，用于在截图上绘制检测框和类别标签
def draw_detection_boxes(screenshot, results):
    # 遍历检测结果中的每个目标
    for result in results:
        # 将检测结果的边界框信息转换为 CPU 上的 numpy 数组
        boxes = result.boxes.cpu().numpy()
        # 遍历每个边界框
        for box in boxes:
            # 获取目标的类别 ID
            class_id = int(box.cls[0])
            # 获取边界框的左上角和右下角坐标
            x1, y1, x2, y2 = box.xyxy[0].astype(int)
            # 计算边界框的中心点坐标
            center_x = int((x1 + x2) / 2)
            center_y = int((y1 + y2) / 2)

            # 在截图上绘制边界框，颜色为绿色，线宽为 2
            cv2.rectangle(screenshot, (x1, y1), (x2, y2), (0, 255, 0), 2)
            # 在边界框上方绘制类别标签
            cv2.putText(screenshot, f"Class {class_id}", (x1, y1 - 10), cv2.FONT_HERSHEY_SIMPLEX, 0.9, (0, 255, 0), 2)

    return screenshot

# 禁用 PyAutoGUI 的安全保护机制，防止鼠标移动到屏幕角落时程序停止
pyautogui.FAILSAFE = False

# 加载 YOLOv8n 模型，并指定使用 GPU 进行推理
model = YOLO(r"h:\yol\yolo\v11\runs\detect\train18\weights\best.pt").to('cuda')

# 调用检测框模块中的 find_window 函数，查找标题中包含'梦幻西游'的窗口
hwnd = 检测框模块.find_window()
if hwnd is None:
    print("未找到标题中包含'梦幻西游'的窗口")
else:
    # 获取窗口的左上角和右下角坐标
    left, top, right, bottom = win32gui.GetWindowRect(hwnd)
    # 计算窗口的宽度
    window_width = right - left
    # 计算窗口的高度
    window_height = bottom - top

    # 商店查找和购买逻辑
    # 定义存储烹饪名称图像的文件夹路径
    cooking_name_folder = r"h:\zdh\yolo2\pengrenm"
    # 定义存储烹饪图像的文件夹路径
    cooking_image_folder = r"h:\zdh\yolo2\pengrent"
    # 获取烹饪名称图像文件夹中的所有图像文件路径
    cooking_names = [os.path.join(cooking_name_folder, f) for f in os.listdir(cooking_name_folder) if os.path.isfile(os.path.join(cooking_name_folder, f))]

    # 初始化找到的烹饪名称为 None
    found_name = None
    # 遍历每个烹饪名称图像
    for cooking_name in cooking_names:
        try:
            # 在屏幕上查找烹饪名称图像，置信度设置为 0.9
            location = pyautogui.locateOnScreen(cooking_name, confidence=0.9)
            if location is not None:
                # 如果找到图像，获取图像的文件名
                found_name = os.path.basename(cooking_name)
                print(f"找到要买的东西: {cooking_name}")
                break
        except pyautogui.ImageNotFoundException:
            # 如果未找到图像，打印提示信息
            print(f"未找到图像: {cooking_name}")

    if found_name:
        # 构建对应的烹饪图像的路径
        cooking_image_path = os.path.join(cooking_image_folder, found_name)
        try:
                def action_a():
                    pyautogui.hotkey('alt', 'e')  # 打开道具栏
                find_class_and_perform_action(hwnd, model, 18, action_a)  # 没看到旗子就重新打开道具栏

                def action_a():
                    movefb(hwnd, left, top, window_width, window_height, model, 要点击的目标类=18, offset_x=-10,
                           offset_y=-10,
                           置信度=0.3, click_type='right', )

                find_class_and_perform_action(hwnd, model, 25, action_a)

                def action():  # 定义动作,找到类就做某事
                    movefb(hwnd, left, top, window_width, window_height, model, 要点击的目标类=25, offset_x=0,
                           offset_y=-10, 置信度=0.3, click_type='left')  # 点击江南传送点
                find_and_perform_action(hwnd, model, 25, action)
                pyautogui.hotkey('alt', 'e')

                # ================点掉对话框
                def action():  # 定义动作,找到类就做某事
                    movefb(hwnd, left, top, window_width, window_height, model, 要点击的目标类=5, offset_x=-100,
                           offset_y=50,
                           置信度=0.3, click_type='left')  # 点掉对话框

                find_and_perform_action(hwnd, model, 5, action)
                click_target_image(r"h:\zdh\yolo2\png\sd.png", offset_x=0, offset_y=0, click_type='right')
                # 点击烹饪名称图像的中心位置


                # 等待 1 秒，让界面更新
                time.sleep(0.2)
                # 在屏幕上查找烹饪图像，置信度设置为 0.6
                location = pyautogui.locateOnScreen(cooking_image_path, confidence=0.96)
                if location is not None:
                    # 如果找到烹饪图像，点击其中心位置
                    pyautogui.click(pyautogui.center(location))
                    print(f"成功找到并点击购买 {found_name}")
                else:
                    print(f"未找到 {found_name}，点击关闭")
                    # 假设关闭按钮对应的类别 ID 为 28，调用 movefb 函数点击关闭按钮
        except pyautogui.ImageNotFoundException:
            # 如果未找到烹饪图像，打印提示信息
            print(f"未找到图像: {cooking_image_path}")
    else:
        print("未找到匹配的烹饪名字")

    #

    # 保存游戏窗口截图
    # 调用检测框模块中的 get_window_screenshot 函数获取游戏窗口的截图
    screenshot = 检测框模块.get_window_screenshot(hwnd)
    # 定义保存截图的文件夹路径
    save_dir = r"h:\yol\ultralytics\datasets\mycp\images"
    if not os.path.exists(save_dir):
        # 如果文件夹不存在，则创建该文件夹
        os.makedirs(save_dir)
    # 构建保存截图的文件路径，文件名包含当前时间戳
    save_path = os.path.join(save_dir, f"screenshot_{int(time.time())}.png")
    # 将截图保存到指定路径
    cv2.imwrite(save_path, screenshot)
    print(f"游戏窗口截图已保存到 {save_path}")

    # 开始分任务流程，启动目标脚本，暂停当前脚本
    # 使用 subprocess 模块启动另一个 Python 脚本 分地图.py
    subprocess.run([sys.executable, "分地图.py"], check=False)
    print("尝试启动分地图")

    # 定义一个函数，用于在没香了的情况下吃香
    def action_a():
        print("没香了，吃香。")
        # 按下热键 Alt+E
        pyautogui.hotkey('alt', 'e')
        # 调用 movefb 函数点击类别 ID 为 81 的目标，设置偏移量和置信度
        movefb(hwnd, left, top, window_width, window_height, model, 要点击的目标类=81, offset_x=0, offset_y=0,
               置信度=0.3, click_type='right')

    # 调用 find_class_and_perform_action 函数，查找类别 ID 为 43 的目标，若未找到则执行 action_a 函数
    find_class_and_perform_action(hwnd, model, 43, action_a)

# 关闭所有 OpenCV 窗口
cv2.destroyAllWindows()